/*
 * Copyright (C) 2012 mAPPn.Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.mol.market.common.network;

import java.net.URLEncoder;
import java.util.Iterator;
import java.util.Set;

import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.os.Bundle;

import com.mol.market.common.util.XmlElement;

/**
 * API请求对象。
 * <p/>
 * Author: Andrew.Wang
 * Date  : 12-9-25
 * Since : Version 0.9.6
 */
public class ApiRequest {

    /**
     * Get method
     */
    public static final int GET = 0;

    /**
     * Post method
     */
    public static final int POST = 1;

    /**
     * 请求ID
     */
    final int actionId;

    /**
     * Request method
     */
    final int requestMethod;

    /**
     * 请求地址
     */
    String url;

    /**
     * 请求参数
     */

    final Bundle args;

    /**
     * Request header
     */
    Bundle requestHeader;

    /**
     * Request body
     */
    String requestBody;

    public ApiRequest(int actionId, int method) {
        this.actionId = actionId;
        this.requestMethod = method;
        this.url = MarketAPI.API_URLS[actionId];
        this.args = new Bundle();
        this.requestHeader = new Bundle();
    }

//  /**
//   * Add http request header.
//   *
//   * @param key
//   * @param value
//   * @return
//   */
//  public void addHeader(String key, String value) {
//    this.requestHeader.putString(key, value);
//  }
//
//  /**
//   * 设置请求参数。
//   *
//   * @param key   参数名
//   * @param value 参数值
//   */
//  public void addParameter(String key, String value) {
//    this.args.putString(key, value);
//  }

    /**
     * 创建API Request时发生的异常。
     */
    public static class RequestBuildException extends Throwable {

        public RequestBuildException(String detailMessage, Throwable throwable) {
            super(detailMessage, throwable);
        }
    }

    public static class Builder {

        /**
         * Application
         */
        private Context mContext;

        /**
         * API请求对象
         */
        private ApiRequest mRequest;

        /**
         * 构造器
         *
         * @param ctx      Application Context
         * @param actionId API请求ID
         */
        public Builder(Context ctx, int method, int actionId) {
            mContext = ctx;
            mRequest = new ApiRequest(actionId, method);
            ApiRequestProxy.doProxy(ctx, mRequest);
        }

        /**
         * 设置请求参数。
         *
         * @param key   参数名
         * @param value 参数值
         */

        public Builder addParameter(String key, String value) {
            mRequest.args.putString(key, value);
            return this;
        }

        /**
         * 设置请求参数。
         *
         * @param key   参数名
         * @param value 参数值
         */

        public Builder addParameter(String key, int value) {
            mRequest.args.putString(key, String.valueOf(value));
            return this;
        }

        /**
         * Add request header.
         *
         * @param key   参数名
         * @param value 参数值
         */

        public Builder addHeader(String key, String value) {
            mRequest.requestHeader.putString(key, value);
            return this;
        }

        /**
         * 返回构造完毕的请求参数。
         */
        public ApiRequest build() throws RequestBuildException {

            if (POST == mRequest.requestMethod) {

                // TODO or xml parameter
//                try {
                mRequest.requestBody =
                        buildXmlRequestBody(mContext, mRequest.args);
//                        buildJsonRequestBody(mRequest.args);
//                } catch (JSONException e) {
//                    throw new RequestBuildException("", e);
//                }

            } else if (GET == mRequest.requestMethod) {

                Iterator<String> keys = mRequest.args.keySet().iterator();

                if (keys.hasNext()) {
                    StringBuilder params = new StringBuilder();

                    while (keys.hasNext()) {
                        String key = keys.next();
                        params.append(key);
                        params.append("=");
                        params.append(URLEncoder.encode(mRequest.args.getString(key)));
                        params.append("&");
                    }

                    // remove the last [&]
                    params.deleteCharAt(params.length() - 1);

                    // rewrite the url to add request parameter
                    mRequest.url = mRequest + "?" + params.toString();
                }
            }

            return mRequest;
        }

        /**
         * Generate the API JSON request body
         */
        private static String buildJsonRequestBody(Bundle args) throws JSONException {

            if (args == null || args.keySet().size() == 0) {
                return "";
            }

            // add parameter node
            final Iterator<String> keySet = args.keySet().iterator();
            JSONObject jsonObject = new JSONObject();
//            try {
            while (keySet.hasNext()) {
                String key = keySet.next();
                jsonObject.put(key, args.getString(key));
            }
//            } catch (JSONException e) {
//                Utils.D("buildJsonRequestBody occur error", e);
//            }
            return jsonObject.toString();
        }

        /**
         * Generate the API XML request body
         */
        @SuppressWarnings("unchecked")
        private static String buildXmlRequestBody(Context context, Bundle params) {

            XmlElement root = new XmlElement("request");
            // 2010/12/29 update version to 2 to get comments from bbs
            root.setAttribute("version", "2");

            if (params == null || params.keySet().size() == 0) {
                return root.toString();
            }

            // all parameter keys
            Set<String> keySet = params.keySet();

            // add local_version parameter if exist
            String localVersion = "local_version";
            if (keySet.contains(localVersion)) {
                root.setAttribute(localVersion, params.getString(localVersion));
                keySet.remove(localVersion);
            }

            // add parameter node
            final Iterator<String> keys = keySet.iterator();
            while (keys.hasNext()) {

                final String key = keys.next();
                // TODO other data type
                final String value = params.getString(key);
				if ("pkgs".equals(key)) {
					StringBuffer buf = new StringBuffer();
					String[] pkgs = value.split(";");
					if (pkgs != null) {
						for (String pkg : pkgs) {
							buf.append("<packagename>").append(pkg);
							buf.append("</packagename>");
						}
					}
					continue;
				}
                XmlElement child = new XmlElement(key);
                
                child.addText(value);
                root.addChild(child);
            }

//        if ("installation".equals(key)) {
//          // 为返利平台添加的API请求
//          ArrayList<HashMap<String, Object>> paramList =
//              (ArrayList<HashMap<String, Object>>) requestParams.get(key);
//          for (HashMap<String, Object> item : paramList) {
//            buf.append("<install pkg=\"").append(item.get("pkg")).append("\" ");
//            buf.append("from=\"").append(item.get("from")).append("\" />");
//          }
//          continue;
//        } else if ("upgradeList".equals(key)) {
//          buf.append("<products>");
//          List<PackageInfo> productsList = (List<PackageInfo>) requestParams.get(key);
//          for (PackageInfo info : productsList) {
//            buf.append("<product package_name=\"").append(wrapText(info.packageName));
//            buf.append("\" version_code=\"").append(info.versionCode).append("\"/>");
//          }
//          buf.append("</products>");
//          continue;
//        } else if ("appList".equals(key)) {
//          buf.append("<apps>");
//
//          // 如果用户安装过多应用，会导致主线程耗时太长
//          PackageManager pm = context.getPackageManager();
//          List<PackageInfo> packages = pm.getInstalledPackages(0);
//          for (PackageInfo info : packages) {
//            buf.append("<app package_name=\"").append(wrapText(info.packageName));
//            buf.append("\" version_code=\"").append(info.versionCode);
//            buf.append("\" version_name=\"").append(wrapText(info.versionName));
//            buf.append("\" app_name=\"").append(
//                wrapText(String.valueOf(info.applicationInfo.loadLabel(pm))));
//            buf.append("\"/>");
//          }
//          buf.append("</apps>");
//          continue;
//        }
//
//        buf.append("<").append(key).append(">");
//
//        try {
//          buf.append(wrapText(String.valueOf(requestParams.get(key))));
//        } catch (Exception e) {
//          Utils.D("wrap text", e);
//        }
//        buf.append("</").append(key).append(">");
            return root.toString();
        }
    }

}
